﻿namespace Timo.Common.Extension;

public static class DataTableHelper
{
    /// <summary>
    /// json字符串转DataTable
    /// </summary>
    /// <param name="json"></param>
    /// <returns></returns>
    public static DataTable? ToDataTable(this string json)
    {
        var table = default(DataTable);
        if (string.IsNullOrEmpty(json))
            return table;
        try
        {
            table = JsonConvert.DeserializeObject<DataTable>(json);
        }
        catch
        {
            return table;
        }
        return table;
    }

    /// <summary>
    /// 将指定的集合转换成DataTable。
    /// </summary>
    /// <param name="list">将指定的集合。</param>
    /// <returns>返回转换后的DataTable。</returns>
    public static DataTable ToDataTable(this IList list)
    {
        DataTable table = new DataTable();
        if (list.Count > 0)
        {
            PropertyInfo[] propertys = list[0].GetType().GetProperties();
            foreach (PropertyInfo pi in propertys)
            {
                Type pt = pi.PropertyType;
                if ((pt.IsGenericType) && (pt.GetGenericTypeDefinition() == typeof(Nullable<>)))
                {
                    pt = pt.GetGenericArguments()[0];
                }
                table.Columns.Add(new DataColumn(pi.Name, pt));
            }

            for (int i = 0; i < list.Count; i++)
            {
                ArrayList tempList = new ArrayList();
                foreach (PropertyInfo pi in propertys)
                {
                    object obj = pi.GetValue(list[i], null);
                    tempList.Add(obj);
                }
                object[] array = tempList.ToArray();
                table.LoadDataRow(array, true);
            }
        }
        return table;
    }

    public static DataTable ToDataTable<T>(this List<T> list)
    {
        DataTable table = new DataTable();
        //创建列头
        PropertyInfo[] propertys = typeof(T).GetProperties();
        foreach (PropertyInfo pi in propertys)
        {
            Type pt = pi.PropertyType;
            if ((pt.IsGenericType) && (pt.GetGenericTypeDefinition() == typeof(Nullable<>)))
            {
                pt = pt.GetGenericArguments()[0];
            }
            table.Columns.Add(new DataColumn(pi.Name, pt));
        }
        //创建数据行
        if (list.Count > 0)
        {
            for (int i = 0; i < list.Count; i++)
            {
                ArrayList tempList = new ArrayList();
                foreach (PropertyInfo pi in propertys)
                {
                    object obj = pi.GetValue(list[i], null);
                    tempList.Add(obj);
                }
                object[] array = tempList.ToArray();
                table.LoadDataRow(array, true);
            }
        }
        return table;
    }

    public static T ToEntity<T>(this DataTable table) where T : new()
    {
        T entity = new T();
        foreach (DataRow row in table.Rows)
        {
            foreach (var item in entity.GetType().GetProperties())
            {
                if (row.Table.Columns.Contains(item.Name))
                {
                    if (DBNull.Value != row[item.Name])
                    {
                        Type newType = item.PropertyType;
                        //判断type类型是否为泛型，因为nullable是泛型类,
                        if (newType.IsGenericType
                                && newType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))//判断convertsionType是否为nullable泛型类
                        {
                            //如果type为nullable类，声明一个NullableConverter类，该类提供从Nullable类到基础基元类型的转换
                            System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(newType);
                            //将type转换为nullable对的基础基元类型
                            newType = nullableConverter.UnderlyingType;
                        }

                        item.SetValue(entity, Convert.ChangeType(row[item.Name], newType), null);

                    }

                }
            }
        }

        return entity;
    }

    public static List<T> ToEntities<T>(this DataTable table) where T : new()
    {
        List<T> entities = new List<T>();
        if (table == null)
            return null;
        foreach (DataRow row in table.Rows)
        {
            T entity = new T();
            foreach (var item in entity.GetType().GetProperties())
            {
                if (table.Columns.Contains(item.Name))
                {
                    if (DBNull.Value != row[item.Name])
                    {
                        Type newType = item.PropertyType;
                        //判断type类型是否为泛型，因为nullable是泛型类,
                        if (newType.IsGenericType
                                && newType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))//判断convertsionType是否为nullable泛型类
                        {
                            //如果type为nullable类，声明一个NullableConverter类，该类提供从Nullable类到基础基元类型的转换
                            System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(newType);
                            //将type转换为nullable对的基础基元类型
                            newType = nullableConverter.UnderlyingType;
                        }
                        item.SetValue(entity, Convert.ChangeType(row[item.Name], newType), null);
                    }
                }
            }
            entities.Add(entity);
        }
        return entities;
    }


}
